package Q9_02_Social_Network; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Queue; public class QuestionB { public static LinkedList<Person> mergePaths(BFSData bfs1, BFSData bfs2, int connection) { PathNode end1 = bfs1.visited.get(connection); // end1 -> source PathNode end2 = bfs2.visited.get(connection); // end2 -> dest LinkedList<Person> pathOne = end1.collapse(false); // forward: source -> connection LinkedList<Person> pathTwo = end2.collapse(true); // reverse: connection -> dest pathTwo.removeFirst(); // remove connection pathOne.addAll(pathTwo); // add second path return pathOne; } /* Search one level and return collision, if any. */ public static Person searchLevel(HashMap<Integer, Person> people, BFSData primary, BFSData secondary) { /* We only want to search one level at a time. Count how many nodes are currently in the primary's * level and only do that many nodes. We'll continue to add nodes to the end. */ int count = primary.toVisit.size(); for (int i = 0; i < count; i++) { /* Pull out first node. */ PathNode pathNode = primary.toVisit.poll(); int personId = pathNode.getPerson().getID(); /* Check if it's already been visited. */ if (secondary.visited.containsKey(personId)) { return pathNode.getPerson(); } /* Add friends to queue. */ Person person = pathNode.getPerson(); ArrayList<Integer> friends = person.getFriends(); for (int friendId : friends) { if (!primary.visited.containsKey(friendId)) { Person friend = people.get(friendId); PathNode next = new PathNode(friend, pathNode); primary.visited.put(friendId, next); primary.toVisit.add(next); } } } return null; } public static LinkedList<Person> findPathBiBFS(HashMap<Integer, Person> people, int source, int destination) { BFSData sourceData = new BFSData(people.get(source)); BFSData destData = new BFSData(people.get(destination)); while (!sourceData.isFinished() && !destData.isFinished()) { /* Search out from source. */ Person collision = searchLevel(people, sourceData, destData); if (collision != null) { return mergePaths(sourceData, destData, collision.getID()); } /* Search out from destination. */ collision = searchLevel(people, destData, sourceData); if (collision != null) { return mergePaths(sourceData, destData, collision.getID()); } } return null; } public static void main(String[] args) { int nPeople = 11; HashMap<Integer, Person> people = new HashMap<Integer, Person>(); for (int i = 0; i < nPeople; i++) { Person p = new Person(i); people.put(i, p); } int[][] edges = {{1, 4}, {1, 2}, {1, 3}, {3, 2}, {4, 6}, {3, 7}, {6, 9}, {9, 10}, {5, 10}, {2, 5}, {3, 7}}; for (int[] edge : edges) { Person source = people.get(edge[0]); source.addFriend(edge[1]); Person destination = people.get(edge[1]); destination.addFriend(edge[0]); } int i = 1; int j = 10; LinkedList<Person> path1 = findPathBiBFS(people, i, j); Tester.printPeople(path1); } }